"""
账号的相关views
"""
# 引入render
from django.shortcuts import render, HttpResponse, redirect, reverse
# 引入表单的类
from web.forms.account import RegisterForm, LoginForm, SmsLoginForm, ResetPasswordForm, DemoForm, SmsSendForm
# 引入图片验证码的模块
from utils.imagecode.image_code import check_code
# 引入内存的二进制数据操作模块
from io import BytesIO
# 引入腾讯云sms模块
from utils.tencent.sms import send_sms_single
# 引入随机值模块
import random
# 引入项目的配置文件settings
from django.conf import settings
# 引入JsonResponse
from django.http import JsonResponse
# 引入正则表达式模块
import re
# 引入Models中的类
from web import models
# 引入redis
from django_redis import get_redis_connection
# 导入Q函数
from django.db.models import Q


def user_register(request):
    """用户注册"""
    if request.method == "GET":
        # 实例化一个表单的对象
        form = RegisterForm()
        # 携带对象到模板中去渲染
        return render(request, 'register.html', {'form': form})
    # ==== POST ===提交
    form = RegisterForm(data=request.POST)
    # 校验
    if form.is_valid():
        # 所有的字段都通过校验
        # 1. 写入到数据库
        form.save()
        # 2. 返回
        return JsonResponse({'status': True, 'url': '/v1/login/'})
    # 至少有个一个字段没通过校验
    return JsonResponse({'status': False, 'errors': form.errors})


def user_login(request):
    """用户登陆"""
    if request.method == "GET":
        # 实例化一个登录的表单对象
        form = LoginForm(request)
        # 携带对象到模板中去渲染
        return render(request, 'login.html', {'form': form})
    # 携带表单数据初始化form表单
    form = LoginForm(request, data=request.POST)
    # 完成验证
    if form.is_valid():
        # 表单输入全部通过校验！
        # ==================完成身份验证==================
        # 获取输入的用户名和密码
        login_name = form.cleaned_data['login_name']
        password = form.cleaned_data['password']
        # 身份验证
        user_object = models.UserInfo.objects.filter(
            Q(login_name=login_name) | Q(email=login_name) | Q(mobile_phone=login_name)).filter(
            password=password).first()
        # 判断是否有用户
        if user_object:
            # 身份验证成功！
            # 把当前用户写入session
            request.session['id'] = user_object.id
            request.session.set_expiry(60 * 60 * 24 * 14)  # 14天

            return JsonResponse({'status': True})

        form.add_error('login_name', '用户名或者密码错误！')

    # 至少有一个没有通过校验
    return JsonResponse({'status': False, 'errors': form.errors})


def user_logout(request):
    """实现用户退出，注销"""
    request.session.flush()
    return redirect(reverse('login'))


def user_sms_login(request):
    """手机验证码登录"""
    if request.method == "GET":
        # 实例化一个表单
        form = SmsLoginForm()
        # 在页面渲染表单
        return render(request, 'smslogin.html', {'form': form})
    # 初始化填好的表单
    form = SmsLoginForm(data=request.POST)
    # 验证
    if form.is_valid():
        # 所有的都通过校验
        # 写入到session
        user_object = form.cleaned_data['mobile_phone']
        request.session['id'] = user_object.id
        request.session.set_expiry(60 * 60 * 24 * 14)
        # 返回
        return JsonResponse({'status': True})
    return JsonResponse({'status': False, 'errors': form.errors})


def user_reset_password(request):
    """重置密码"""
    if request.method == "GET":
        # 实例化一个表单
        form = ResetPasswordForm()
        # 在页面渲染表单
        return render(request, 'resetpassword.html', {'form': form})
    # =====POST请求，携带数据，实例化表单，验证====
    form = ResetPasswordForm(data=request.POST)
    # 校验
    if form.is_valid():
        pass
    # ================= 校验 ==========
    # 获取password
    password = request.POST.get('password')
    # 获取哪些字段出现错误
    errors_key = form.errors.keys()
    # 判断是第一步校验还是第二步校验
    if not password:
        # ===== 第一步 =====
        if ('mobile_phone' not in errors_key) and ('code' not in errors_key):
            return JsonResponse({'status': True})
        # 如果mobile_phone , code 有一个校验失败
        return JsonResponse({'status': False, 'errors': form.errors})
    else:
        # =====第二步
        if ('password' not in errors_key) and ('re_password' not in errors_key):
            # 修改密码
            password = form.cleaned_data.get('password')
            user_object = form.cleaned_data.get('mobile_phone').update(passwor=password)


            # 修改
            # //user_object.password = password
            # uer_object.save()
            # 返回
            return JsonResponse({'status': True})
        return JsonResponse({'status': False, 'errors': form.errors})


def image_code(request):
    """图片验证码"""
    # 获取图片验证码
    image_obj, code = check_code()
    # 把正确的验证码文本存储的session中
    request.session['image_code'] = code
    request.session.set_expiry(60)  # 有效期60s

    # 实例化一个操作对象
    stream = BytesIO()
    # 保存在内存中--png格式
    image_obj.save(stream, 'png')
    # 返回给前段
    return HttpResponse(stream.getvalue())


"""
# ================   实现短信发送的方法01 ===============
def sms_send(request):
  
    # 接收前台发送过来的数据 --- POST
    mobile_phone = request.POST.get('mobile_phone')
    tpl = request.POST.get('tpl')  # register

    # 判断---tpl的字符串是否正确 --- 是否能取到短信模板的id
    tpl_id = settings.TENCENT_SMS['templates'].get(tpl)
    # 如果取不到，报错
    if not tpl_id:
        return JsonResponse({'status': False, 'errmsg': '短信模板编号无法获取！'})

    # 判断 --- 手机号码是否为空！
    if len(mobile_phone.strip()) == 0:
        return JsonResponse({'status': False, 'errmsg': '手机号码不能为空！'})
    # 判断 ---- 手机号码是否符合格式规范-- 11位数字，第一位1，--- 正则表达式
    if not re.match(r'^[1][345789]\d{9}$', mobile_phone):
        return JsonResponse({'status': False, 'errmsg': '手机号码不符合规范！'})

    # 判断 ---- 注册--- 数据库中要没有
    is_exsits = models.UserInfo.objects.filter(mobile_phone=mobile_phone).exists()
    # 判断是否存在
    if is_exsits:
        return JsonResponse({'status': False, 'errmsg': '手机号码已注册！'})

    # 准备开发发送短信
    code = random.randint(1000, 9999)
    # 开始发送
    tencent_res = send_sms_single(mobile_phone, tpl_id, [code, ])
    # 判断短信是否发送成功
    if tencent_res['result'] != 0:
        # 展示腾讯返回的错误
        return JsonResponse({'status': False, 'errmsg': '短信发送异常！具体原因：%s' % (tencent_res['errmsg'])})

    # ===== 发送成功 ======
    # 把验证码写入 redis  13482034096: code
    # 获取一个连接
    conn = get_redis_connection("default")
    # 写入一个记录
    conn.set(mobile_phone, code, ex=60)
    # 返回
    return JsonResponse({'status': True, 'errmsg': 'Ok'})
"""


def sms_send(request):
    """用于发送短信"""
    # 实例化表单
    form = SmsSendForm(request, data=request.POST)
    # 校验
    if form.is_valid():
        # 所有的表单项都通过校验
        return JsonResponse({'status': True})
    else:
        # 至少有一个表单项没通过校验
        return JsonResponse({'status': False, 'errors': form.errors})


def user_demo(request):
    """测试"""
    if request.method == "GET":
        # 实例化一个表单对象
        form = DemoForm()
        # 展示
        return render(request, 'demo.html', {'form': form})

    elif request.method == "POST":
        """
        # 获取表单提交来的数据-- form
        form = DemoForm(data=request.POST)
        # 校验
        if form.is_valid():
            # 所有的字段都通过校验
            return HttpResponse("所有的字段通过校验！")
        else:
            # 至少有一个字段没通过校验！
            return render(request, 'demo.html', {'form': form})
        """
        # 获取表单提交来的数据-- form
        form = DemoForm(data=request.POST)
        # 校验
        if form.is_valid():
            # 返回
            return JsonResponse({'status': True})
        else:
            return JsonResponse({'status': False, 'errors': form.errors})
